package com.bob.clan.wxconnector.controller;

import com.bob.clan.wxconnector.DTO.FansDTO;
import com.bob.clan.wxconnector.DTO.WebAuthorMsgDTO;
import com.bob.clan.wxconnector.component.MpComponent;
import com.bob.clan.wxconnector.entity.Mp;
import com.bob.clan.wxconnector.exception.LoginException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.UnknownHostException;
import java.security.MessageDigest;

/**
 * 模拟服务服务器的服务，仅用于在测试时使用
 */
@Slf4j
@Controller
@RequestMapping("/third/wxDemo/")
public class WXServerDemoController {
    @Autowired
    private MpComponent mpComponent;

    @RequestMapping("/scanLogin")
    public String toLogin(HttpServletRequest request, Model model){
        model.addAttribute("wsIP", request.getServerName()); // 如果需要在视图中使用
        model.addAttribute("wsPort", request.getServerPort()); // 如果需要在视图中使用
        model.addAttribute("wsLocalIP", request.getLocalAddr()); // 如果需要在视图中使用
        model.addAttribute("contextPath", request.getContextPath()); // 如果需要在视图中使用
        return "loginDemo/qrLogin";

    }

    //通过微信方登录
    @RequestMapping("/byWxLogin")
    public String loginSuccess(@ModelAttribute FansDTO fans, HttpServletRequest request, Model model) {
        if (checkRight(fans,model)) {
            String contextPath = request.getContextPath();
            model.addAttribute("contextPath", contextPath); // 如果需要在视图中使用
            model.addAttribute("fans", fans);
            log.info("login successful,fans:" + fans);
            return "loginDemo/qrLoginSuccessful";
        } else {
            return "error";
        }
    }

    private boolean checkRight(FansDTO fans,Model model) {
        if(fans==null){
            model.addAttribute("error", new LoginException(1000));
            log.error("fans为空，无效登录");
            return false;
        }
        if(fans.getOpenid()==null || "".equals(fans.getOpenid())){
            model.addAttribute("error", new LoginException(1001));
            log.error("openid为空，无效登录");
            return false;
        }
        if(fans.getNickname()==null || "".equals(fans.getNickname())){
            model.addAttribute("error", new LoginException(1002));
            log.error("nickname为空，无效登录");
            return false;
        }
        if(fans.getHeadImgUrl()==null || "".equals(fans.getHeadImgUrl())){
            model.addAttribute("error", new LoginException(1003));
            log.error("headImgUrl为空，无效登录");
            return false;
        }
        if(fans.getTimestamp()==null || "".equals(fans.getTimestamp())){
            model.addAttribute("error", new LoginException(1004));
            log.error("时间戳为空，无效登录");
            return false;
        }
        if(fans.getSignature()==null || "".equals(fans.getSignature())){
            model.addAttribute("error", new LoginException(1005));
            log.error("登录签名为空，无效登录");
            return false;
        }
        try {
            Long loginTime = Long.valueOf(fans.getTimestamp());
            Long curTime = System.currentTimeMillis();
            Long maxWaitTime = 5 * 60 * 1000L;
            if (curTime - loginTime > maxWaitTime) {
//            model.addAttribute("errorMsg", "登录超时，请重新再试");
                model.addAttribute("error", new LoginException(2001));
                log.error("扫码登录用时超过5分钟，可能是恶意行为，请阻止！！！");
                return false;
            }
        }catch (NumberFormatException e){
            model.addAttribute("error", new LoginException(1014));
            log.error("时间戳格式非法，无效登录");
            return false;
        }
        String signature = getSHA256(fans);
        if (!fans.getSignature().equals(signature)) {
//            model.addAttribute("errorMsg", "登录签名不一致，请使用全法渠道登录");
            model.addAttribute("error", new LoginException(3001));
            log.error("登录签名不一致，本次为非法登录，请阻止！！！");
            return false;
        }
        log.info("验证通过，合法的扫码登录===");
        return true;
    }

    private String getSHA256(FansDTO fans) {
        String input = fans.getOpenid() + fans.getTimestamp() + fans.getSysCode();
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                hexString.append(String.format("%02x", b));
            }
            return hexString.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 模拟微信服务器给服务号后台发送code(此处为userBase)
     * 注：此处不传secret参数，这是个绝密的参数，在通过code之后，才可以传，微信这了安全保密也是煞费苦心了。
     *
     * @param appid
     * @param redirect_uri
     * @param state
     * @param response
     * @throws IOException
     */
    @RequestMapping("userBase")
    public void getUserBase(String appid, String redirect_uri, String state, HttpServletResponse response) throws IOException {
        String code = String.valueOf("userBase" + System.currentTimeMillis());
        redirect_uri = redirect_uri + "&code=" + code + "&state=" + state;
        log.info("get code userBase OK! redirect_uri:" + redirect_uri);
        response.sendRedirect(redirect_uri);
    }

    /**
     * 模拟微信服务器给服务号后台发送code(此处为userInfo)
     * 注：此处不传secret参数，这是个绝密的参数，在通过code之后，才可以传，微信这了安全保密也是煞费苦心了。
     *
     * @param appid
     * @param redirect_uri
     * @param state
     * @param response
     * @throws IOException
     */
    @RequestMapping("userInfo")
    public void getUserInfo(String appid, String redirect_uri, String state, HttpServletResponse response) throws IOException {
        String code = String.valueOf("userInfo" + System.currentTimeMillis());
        redirect_uri = redirect_uri + "&code=" + code + "&state=" + state;
        log.info("get code userInfo OK! redirect_uri:" + redirect_uri);
        response.sendRedirect(redirect_uri);
    }

    @RequestMapping("accessToken")
    @ResponseBody
    public WebAuthorMsgDTO getAccessTokenAndOpenid(String appid, String secret, String code, HttpServletResponse response) throws IOException {
        Mp mp = mpComponent.getByAppid(appid);
        if (mp != null && mp.getSysCode().equals(secret)) {
            log.info(mp.getName() + "在请求 token");
        } else {
            log.error(appid + "该appid不在 或 secret不匹配，下不为例啊");
        }
        WebAuthorMsgDTO msgDTO = new WebAuthorMsgDTO();
        msgDTO.setAccess_token("accessToken.12121212");
//        msgDTO.setOpenid(code);
        msgDTO.setOpenid("ojpMb5riK6SUJVNiDRydSB9HYFbw");
        log.info("accessToken and openId create,setOpenid:" + code);
        return msgDTO;
    }

    @RequestMapping("fansInfo")
    @ResponseBody
    public WebAuthorMsgDTO getFansInfo(String access_token, String openid) {
        log.info(access_token + "====get access token====");
        WebAuthorMsgDTO msgDTO = new WebAuthorMsgDTO();
        msgDTO.setNickname("bob");
        msgDTO.setHeadimgurl("https://q6.itc.cn/images01/20240514/45eaca3ccb2b463ab03fae716edad8a6.jpeg");
//        msgDTO.setOpenid(openid);
        msgDTO.setOpenid("ojpMb5riK6SUJVNiDRydSB9HYFbw");
        msgDTO.setSex(1);
        return msgDTO;
    }

}
